package vip.liux.gateway.filters.decrypt;

import org.springframework.data.redis.core.ReactiveHashOperations;
import org.springframework.data.redis.core.ReactiveStringRedisTemplate;
import reactor.core.publisher.Mono;

/**
 * 基于Redis Hash结构（响应式）读取 appId 公钥私钥的仓储实现
 */
public class AppKeyRedisRepository implements AppKeyRepository {

    private static final String REDIS_APP_KEY_HASH = "app_key_hash";
    private final ReactiveHashOperations<String, String, String> hashOps;

    public AppKeyRedisRepository(ReactiveStringRedisTemplate redisTemplate) {
        this.hashOps = redisTemplate.opsForHash();
    }

    @Override
    public Mono<KeyPairConfig> getKeyPairConfig(String appId) {
        // Redis Hash结构内的字段名
        String privateField = appId + ":private";
        String publicField = appId + ":public";
        String signSecretField = appId + ":signSecret";
        String externalPrivateKeyField = appId + ":externalPrivateKey";
        String externalPublicKeyField = appId + ":externalPublicKey";

        Mono<String> privateKeyMono = hashOps.get(REDIS_APP_KEY_HASH, privateField);
        Mono<String> publicKeyMono = hashOps.get(REDIS_APP_KEY_HASH, publicField);
        Mono<String> signSecretMono = hashOps.get(REDIS_APP_KEY_HASH, signSecretField);
        Mono<String> externalPrivateKeyMono = hashOps.get(REDIS_APP_KEY_HASH, externalPrivateKeyField);
        Mono<String> externalPublicKeyMono = hashOps.get(REDIS_APP_KEY_HASH, externalPublicKeyField);

        // 只要有一个Mono是empty，zip就不会进入flatMap
        return Mono.zip(privateKeyMono, publicKeyMono, signSecretMono, externalPrivateKeyMono, externalPublicKeyMono)
                .map(tuple ->
                        new KeyPairConfig(tuple.getT1(), tuple.getT2(), tuple.getT3(), tuple.getT4(), tuple.getT5()));
    }
}